
###
 # @Author: didiplus
 # @Description: 等保2.0密码复杂度标准配置
 # @Date: 2025-06-19 17:21:19
 # @LastEditors: didiplus
 # @LastEditTime: 2025-06-19 23:23:43
 # @FilePath: /script/SecGuardian/modules/configure_password_expiration_and_pam_pwquality.sh
 # @Version: 1.0
### 

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # 重置颜色

source ./modules/tools_function.sh

# 等保2.0密码复杂度标准配置
MIN_LEN=12          # 最小长度12位
MIN_CLASS=4         # 至少包含4种字符类型（大小写字母、数字、特殊字符）
UCREDIT=-1          # 至少1个大写字母
LCREDIT=-1          # 至少1个小写字母
DCREDIT=-1          # 至少1个数字
OCREDIT=-1          # 至少1个特殊字符
RETRY=3             # 密码尝试次数
MAX_DAYS=90         # 密码最长有效期
MIN_DAYS=7          # 密码最短有效期
WARN_AGE=14         # 密码到期前提醒天数


# 安装必要组件
install_required() {
    local os_type=$1
    case "$os_type" in
        redhat)
            if ! rpm -q pam_pwquality &>/dev/null; then
                echo -e "${YELLOW}[+] 安装pam_pwquality模块...${NC}"
                yum install -y pam_pwquality || dnf install -y pam_pwquality
            fi
            ;;
        debian)
            if ! dpkg -l libpam-pwquality &>/dev/null; then
                echo -e "${YELLOW}[+] 安装libpam-pwquality模块...${NC}"
                apt-get update
                apt-get install -y libpam-pwquality
            fi
            ;;
        suse)
            if ! rpm -q pam_pwquality &>/dev/null; then
                echo -e "${YELLOW}[+] 安装pam_pwquality模块...${NC}"
                zypper install -y pam_pwquality
            fi
            ;;
    esac
}


# 配置PAM密码复杂度（pwquality）
configure_pam_pwquality() {
    local os_type=$1
    local pam_file=""

    # 确定PAM配置文件路径
    case "$os_type" in
        redhat) pam_file="/etc/pam.d/system-auth" ;;
        debian|suse) pam_file="/etc/pam.d/common-password" ;;
        *) return 1 ;;
    esac

    [ ! -f "$pam_file" ] && return 1

    echo -e "${GREEN}[+] 配置PAM密码复杂度 (pwquality)${NC}"
    cp -p "$pam_file" "${pam_file}.bak_$(date +%s)"

    # 构建配置字符串
    local config="password requisite pam_pwquality.so try_first_pass"
    [ "$os_type" = "redhat" ] && config+=" local_users_only"
    config+=" retry=$RETRY minlen=$MIN_LEN minclass=$MIN_CLASS"
    config+=" ucredit=$UCREDIT lcredit=$LCREDIT dcredit=$DCREDIT ocredit=$OCREDIT"

    # 删除现有配置（如果存在）
    sed -i '/pam_pwquality\.so/d' "$pam_file"

    # 添加新配置
    case "$os_type" in
        redhat)
            sed -i '/password.*pam_unix\.so/i '"$config" "$pam_file"
            ;;
        debian|suse)
            sed -i '/password.*pam_unix\.so/i '"$config" "$pam_file"
            ;;
    esac

    echo -e "密码复杂度要求："
    echo -e "  最小长度: ${MIN_LEN}字符"
    echo -e "  字符类型: ${MIN_CLASS}种（大小写字母、数字、特殊字符）"
    echo -e "  大写字母: ${UCREDIT#-}个"
    echo -e "  小写字母: ${LCREDIT#-}个"
    echo -e "  数字: ${DCREDIT#-}个"
    echo -e "  特殊字符: ${OCREDIT#-}个"
}


# 配置密码有效期
configure_password_expiration() {
    local file="/etc/login.defs"
    [ ! -f "$file" ] && return 1

    echo -e "${GREEN}[+] 配置密码有效期策略${NC}"
    cp -p "$file" "${file}.bak_$(date +%s)"

    sed -i "/^PASS_MAX_DAYS/c\PASS_MAX_DAYS   $MAX_DAYS" "$file"
    sed -i "/^PASS_MIN_DAYS/c\PASS_MIN_DAYS   $MIN_DAYS" "$file"
    sed -i "/^PASS_WARN_AGE/c\PASS_WARN_AGE   $WARN_AGE" "$file"

    echo -e "密码有效期配置完成："
    echo -e "  最长有效期: ${MAX_DAYS}天"
    echo -e "  最短有效期: ${MIN_DAYS}天"
    echo -e "  到期提醒: ${WARN_AGE}天"
}

# 主函数
configure_password_expiration_and_pam_pwquality() {
    echo -e "${YELLOW}\n=== 等保2.0密码复杂度配置工具 ===${NC}"
    
    # 检测系统类型
    local os_type=$(detect_os)
    if [ "$os_type" = "unknown" ]; then
        echo -e "${RED}[!] 不支持的系统类型${NC}"
        return 1
    fi
    echo -e "系统类型: ${GREEN}$os_type${NC}"

    # 安装必要组件
    install_required "$os_type"

    # 配置密码有效期
    configure_password_expiration

    # 尝试配置pwquality
    configure_pam_pwquality "$os_type"


    # 显示最终配置
    echo -e "\n${GREEN}[√] 密码策略配置完成${NC}"
    echo -e "当前密码策略："
    grep -E "^PASS_" /etc/login.defs | grep -v "^#"
    
    case "$os_type" in
        redhat)
            grep -E "pam_pwquality|pam_cracklib" /etc/pam.d/system-auth
            ;;
        debian|suse)
            grep -E "pam_pwquality|pam_cracklib" /etc/pam.d/common-password
            ;;
    esac
}
